<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="apple-touch-icon" href="apple-touch-icon.png">
    <link rel="shortcut icon" href="favicon.ico" />
    <link rel="manifest" href="a3.webmanifest">
    <title>A3Class Basic Shapes</title>
  </head>
  <body>
    <link rel="stylesheet" href="css/main.css"/>
    <script src="js/Theme.js"></script>
    <script src="js/ammo.js/build/ammo.wasm.js"></script>
    <div class="div-fullscreen"><div id="container"></div></div>
    <script type="module">
      import * as THREE from "./js/three.js/build/three.module.js";
      import URDFLoader from './jsm/URDFLoader/URDFLoader.js';

      import A3Class from './js/A3Class.js';
      import A3Actor from './js/A3Actor.js';
      import A3BasicShape from './js/A3BasicShape.js';
      import A3Terrain from './js/A3Terrain.js';
      import A3Path from './js/A3Path.js';
      import { A3SpotLight } from './js/A3Lights.js';
      import A3Flow from './js/A3Flow.js';
      import { A3HingeConstraint, A36DofConstraint, A3SlideConstraint } from './js/A3Constraint.js';
      import { ExCylinderGeometry } from './js/A3Geometrys.js';

      const container = document.getElementById( 'container' );

      const a3 = new A3Class( container );

      await a3.initAmmo();
      a3.init();

      console.log( a3.AmmoLib );
      // console.log( new THREE.Vector3().distanceTo( new THREE.Vector3(1,1,0)))

      const pos = new THREE.Vector3();
      const quat = new THREE.Quaternion( 0, 0, 0, 1 );

      const box = new A3BasicShape("Box");
      box.init(1);
      a3.addActor(box);
      pos.set( 2, 1, 0 );
      box.setPosition( pos );

      const cylinder = new A3BasicShape("Cylinder");
      cylinder.init(1);
      a3.addActor(cylinder);
      pos.x += 1;
      cylinder.setPosition( pos );

      const sphere = new A3BasicShape("Sphere");
      sphere.init(1);

      a3.addActor(sphere);
      pos.x += 1;
      sphere.setPosition( pos );

      const cone = new A3BasicShape("Cone").init(1);
      a3.addActor(cone);
      pos.x += 1;
      cone.setPosition( pos );

      const capsule = new A3BasicShape("Capsule").init(1);
      pos.x += 1;
      pos.y = 8;
      capsule.setPosition( pos );      
      a3.addActor(capsule);
      // capsule.threeObject.material.wireframe = true;

      // 游泳圈
      // const torusGeometry = new THREE.TorusGeometry(2, .2, 24, 24);
      // const torusMesh = new THREE.Mesh( torusGeometry );
      // const torus = new A3Actor();
      // quat.setFromAxisAngle(a3.AxisX, Math.PI / 2);
      // torus.setFromMesh( torusMesh ,1, pos, quat );
      // torus.setMaterial();
      const torus = new A3BasicShape("Torus", 1, .4).init(1);
      // pos.x += 2;
      // pos.y += 1;
      // quat.setFromAxisAngle(a3.AxisX, Math.PI / 2);
      // torus.setMass(0)
      torus.setPosition( pos );
      // torus.setQuaternion( quat );
      // torus.enableWireframe();
      a3.addActor(torus);

      // plane
      // const planeGeometry = new THREE.PlaneGeometry( 10, 10, 1, 1 );
      // const planeMesh = new THREE.Mesh( planeGeometry );
      // console.log( planeGeometry );
      // const plane = new A3Actor();
      // plane.setFromMesh( planeMesh );
      const plane = new A3BasicShape("Plane", 12, 6).init(1);
      // a3.addMesh( planeMesh );
      pos.x = 0;
      pos.y = 2;
      plane.setPosition(pos);
      // plane.setMass(0);
      // plane.enableWireframe();
      a3.addActor( plane );

      // 地形
      const terrain = A3Terrain.waveTerrain( 128, 129, 0, 2, .2 , "cos");
      pos.set( -15, 8, 0 );
      quat.setFromAxisAngle( a3.AxisX, Math.PI / 6)
      terrain.setPosition( pos );
      terrain.setQuaternion( quat );
      terrain.setTexture();
      a3.addActor( terrain );

      a3.addGround(60, 0.1, 60, 'textures/grid.png');

      // a3.removeActor( cone );

      const boxSize = 1.5;

      for(var x = 0; x < 3; x ++){
        for(var y = 0; y < 3; y++){
          const box = new A3BasicShape( "Box", boxSize * 2, boxSize, boxSize, 1 ).init(0.5);
          pos.set( x * boxSize* 2 + boxSize - 5 - 10, y * boxSize + boxSize / 2 + 20, -5);
          box.setPosition(pos);
          // box.setMass(1);
          a3.addActor(box);
          box.enableShadow();
        }
      }

      // 运动测试

      const mBox = new A3BasicShape("Box", 2, 1, 3).init(1);
      pos.set( 10, 0.5, 10 );
      mBox.setPosition( pos );
      // mBox.setLinearVelocity( new THREE.Vector3( 1, 0, 1 ));
      a3.addActor( mBox );

      // 路径
      const path = new A3Path();
      pos.set( 12, 0.5, 12 );
      path.setPosition( pos );

      // path.setQuaternion( quat );
      a3.addActor( path );
      // console.log( path.curve.getPointAt( 0.002 ) )
    
      // 灯光
      const pointLight = new A3SpotLight();
      pointLight.setPosition( pos );
      a3.addActor( pointLight );
      // const box = new a3.A3BasicShape( "Box", 1, 1, 1, 1 );
      // pos.y = 20;
      // box.setPosition(pos);
      // a3.addActor(box)

      const flow = new A3Flow( mBox, path, 0.005 );

      // 约束测试
      const parent = new A3BasicShape("Box", 1,2,1,0 ).init(1);
      pos.set( 10, 1, -10 );
      parent.setPosition( pos );
      a3.addActor( parent );
      parent.setMass(0)
  

      const child = new A3BasicShape("Box", 2,1,1 ).init(1);
      pos.set( 10, 2.5, -10 );
      child.setPosition( pos );
      a3.addActor( child );

      const hinge = new A3HingeConstraint( parent, child );
      hinge.setBodyA( new THREE.Vector3(0, 1.5, 0), new THREE.Vector3( 0, 1, 0 ) );
      hinge.setBodyB( new THREE.Vector3(0, 0, 0), new THREE.Vector3( 0, 1, 0 ));
      a3.addActor(hinge);

      hinge.enableConstraint(true, 20);

      const child6Dof = new A3BasicShape("Capsule", .5,1 ).init(1);
      pos.set( 10, 2.5, -12 );
      child6Dof.setPosition( pos );
      a3.addActor( child6Dof );
      // child6Dof.setLinearVelocity(new THREE.Vector3( 1, 0, 0 ) );

      const c6dof = new A36DofConstraint( parent, child6Dof );
      a3.addActor(c6dof);

      c6dof.setBodyA( new THREE.Vector3(0, 0.5, 0) );
      c6dof.setBodyB( new THREE.Vector3(0, 0.5, 0), new THREE.Vector3(0, 1, 0) );
      c6dof.enableConstraint();

      c6dof.setLinearLowerLimit( new THREE.Vector3(-1.2, .25, -1.5) );
      c6dof.setLinearUpperLimit( new THREE.Vector3(1 , .25, -1.5) );

      c6dof.setAngularLowerLimit( new THREE.Vector3(0, -1, 0 ) );
      c6dof.setAngularUpperLimit( new THREE.Vector3(0, 1, 0 ) );

      const childSlider = new A3BasicShape("Box").init(1);
      pos.set( 12, 0.5, -12 );
      childSlider.setPosition( pos );
      a3.addActor( childSlider );

      const slider = new A3SlideConstraint( parent, childSlider );
      a3.addActor(slider);

      slider.setBodyA( new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 1, 0) );
      slider.setBodyB( new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 0, 1) );
      slider.enableConstraint();

      console.log( slider.constraint)
      // childSlider.setLinearVelocity( new THREE.Vector3( 1, 1, 1 ) );

      slider.setLinearLowerLimit( -10 );
      slider.setLinearUpperLimit( 10 );

      slider.enableLinMotor( true, 1, 10 );

      slider.setAngularLowerLimit( Math.PI / 4 );
      slider.setAngularUpperLimit( Math.PI / 4 );
      
      let clock = new THREE.Clock();
      
      var pathPos = 0;

      a3.start();
      animate();

      function animate() {

        requestAnimationFrame( animate );

        if( pathPos < 1 ) {
          const tmpPos = path.getPointAt( pathPos );

          pointLight.setPosition( tmpPos );
          // mBox.setPosition( tmpPos );
          // const force = new THREE.Vector3( 4, 0, 0 );
          // force.applyQuaternion( path.getQuaternionAt( pathPos ));

          // // mBox.applyForce( force );
          // mBox.setLinearVelocity( force );
          // pointLight.setQuaternion( path.quaternion );
          pathPos += 0.001;
        }
        else {
           pathPos = 0;
        }
        const delta = clock.getDelta();

        flow.update( delta );

      }

    </script>
  </body>
</html>